﻿/*
// Exepack.NET
// http://www.codeplex.com/exepack
//
// Temporary file manager
// Written by Y [06-03-09]
// Copyright (c) 2008-2009 Alexey Yakovlev
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Exepack
{
	/// <summary>
	/// Manages temporary directory and files, 
	/// either inside or outside temporary directory
	/// </summary>
	class TempFileManager : IDisposable
	{
		public TempFileManager()
		{
			CreateTemporaryDirectory();
			Files = new List<string>();
		}

		public TempFileManager(bool forceCleanup)
			: this()
		{
			ForceCleanup = forceCleanup;
		}

		~TempFileManager()
		{
			Dispose();
		}

		/// <summary>
		/// Deletes registered temporary files and directory
		/// </summary>
		public void Dispose()
		{
			// check if already disposed
			if (DirectoryName == null)
			{
				return;
			}

			try
			{
				// delete registered temporary files
				foreach (string fileName in Files)
				{
					File.Delete(this[fileName]);
				}
			}
			catch
			{
				// by default, clean up ignores errors
				if (ThrowExceptionsOnCleanup)
					throw;
			}
			finally
			{
				Files.Clear();
			}

			try
			{
				// clean up temporary directory
				Directory.Delete(DirectoryName, ForceCleanup);
			}
			catch
			{
				// by default, clean up ignores all exceptions
				if (ThrowExceptionsOnCleanup)
					throw;
			}
			finally
			{
				DirectoryName = null;
			}
		}

		/// <summary>
		/// Creates directory with random name
		/// </summary>
		private void CreateTemporaryDirectory()
		{
			DirectoryName = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
			Directory.CreateDirectory(DirectoryName);
		}

		/// <summary>
		/// Registers file as temporary and returns full name inside the temporary directory
		/// </summary>
		public string this[string fileName]
		{
			get
			{
				// register file for cleanup
				if (!Files.Contains(fileName))
				{
					Files.Add(fileName);
				}

				// if full path is specified, don't add temporary directory name
				if (Path.IsPathRooted(fileName))
				{
					return fileName;
				}

				// put the file inside temporary directory
				return Path.Combine(DirectoryName, fileName);
			}
		}

		/// <summary>
		/// Directory to hold temporary files
		/// Will be cleaned up automatically
		/// </summary>
		public string DirectoryName { get; private set; }

		/// <summary>
		/// Temporary file list
		/// Files are not necessarily located in temporary directory
		/// </summary>
		public List<string> Files { get; private set; }

		/// <summary>
		/// Set to true if temporary directory should be deleted even if not empty
		/// </summary>
		public bool ForceCleanup { get; set; }

		/// <summary>
		/// Set to true if you want to handle exceptions on cleanup yourself
		/// </summary>
		public bool ThrowExceptionsOnCleanup { get; set; }
	}
}
